#include <iostream>
#include <limits>

using std::cout;
using std::endl;
using std::cin;

class Complex
{
    friend class Point;
public:
    Complex(double dreal = 0.0, double dimag = 0.0)
    : _dreal(dreal)
    , _dimag(dimag)
    {
        cout << "Complex(double = 0.0, double = 0.0)" << endl;
    }

    ~Complex()
    {
        cout << "~Complex()" << endl;
    }

    friend std::ostream &operator<<(std::ostream &os, const Complex &rhs);
    friend std::istream &operator>>(std::istream &is, Complex &rhs);
private:
    double _dreal;
    double _dimag;
};

std::ostream &operator<<(std::ostream &os, const Complex &rhs)
{
    cout << "std::ostream &operator<<(std::ostream &, const Complex &)" << endl;
    if(0 == rhs._dreal && 0 == rhs._dimag)
    {
        os << 0 << endl;
    }
    else if(0 == rhs._dreal)
    {
        os << rhs._dimag << "i" << endl;
    }
    else
    {
        os << rhs._dreal;
        if(rhs._dimag > 0)
        {
            os << " + " << rhs._dimag << "i" << endl;
        }
        else if(0 == rhs._dimag)
        {
            os << endl;
        }
        else
        {
            os << " - " << (-1) * rhs._dimag << "i" << endl;
        }
    }

    return os;
}

void readDouble(std::istream &is, double &number)
{
    while(is >> number, !is.eof())//真值表达式
    {
        if(is.bad())
        {
            cout << "stream is bad" << endl;
            return;
        }
        else if(is.fail())
        {
            is.clear();
            is.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
            cout << "pls input double data" << endl;
        }
        else 
        {
            cout << "number = " << number << endl;
            break;
        }
    }
}

std::istream &operator>>(std::istream &is, Complex &rhs)
{
    cout << "std::istream &operator>>(std::istream &, Complex &)" << endl;
    readDouble(is, rhs._dreal);
    readDouble(is, rhs._dimag);

    return is;
}

class Point
{
public:
    Point(int ix = 0, int iy = 0)
    : _ix(ix)
    , _iy(iy)
    {
        cout << "Point(int = 0, int = 0)" << endl;
    }

    Point(const Complex &rhs)
    : _ix(rhs._dreal)
    , _iy(rhs._dimag)
    {
        cout << "Point(const Complex &)" << endl;
    }

    ~Point()
    {
        cout << "~Point()" << endl;
    }

    //类型转换函数
    //1、必须是一个成员函数
    //2、函数没有参数列表
    //3、函数没有返回类型
    //4、在函数体中执行return语句，返回目标类型的变量
    //5、一般不建议使用这个语法
    operator int()
    {
        cout << "operator int()" << endl;
        return _ix + _iy;
    }

    operator double()
    {
        cout << "operator double()" << endl;
        if(0 == _iy)
        {
            return 0.0;
        }
        else
        {
            return static_cast<double>(_ix)/_iy;
        }
    }

    operator Complex()
    {
        cout << "operator Complex()" << endl;
        return Complex(_ix, _iy);
    }

    friend std::ostream &operator<<(std::ostream &os, const Point &rhs);
private:
    int _ix;
    int _iy;
};

std::ostream &operator<<(std::ostream &os, const Point &rhs)
{
    os << "(" << rhs._ix
       << ", " << rhs._iy
       << ")";
    return os;
}

void test()
{
    Point pt(1, 2);
    cout << "pt = " << pt << endl;

    cout << endl;
    //从其他类型向自定义类型进行转换
    //隐式转换
    Point pt2 = 100;//int---->Point,100--->Point(100, 0)
    cout << "pt2 = " << pt2 << endl;

    cout << endl;
    Complex c2(2, 3);
    cout << "c2 = " << c2 << endl;
    //Complex--->Point
    Point pt3 = c2;
    cout << "pt3 = " << pt3 << endl;
}

void test2()
{
    //从自定义类型向其他类型进行转换
    Point pt(1, 2);
    cout << "pt = " << pt << endl;

    cout << endl;
    int ix = pt;
    cout << "ix = " << ix << endl;

    cout << endl;
    double dy = pt;
    cout << "dy = " << dy << endl;

    cout << endl;
    Complex c1 = pt;
    cout << "c1 = " << c1 << endl;
}

int main(int argc, char *argv[])
{
    test2();
    return 0;
}

